package com.etlmaster.rowprocessor.core;

import java.text.DecimalFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Larry
 * @copyright Larry@etlMaster
 * @since 2017-09-10
 */
public class Monitor {
	private Date upTime = new Date();

	private Map<String, SpeedMeta> speedInfo = new HashMap<String, SpeedMeta>();

	public String toString(Job job) {
		Date now = new Date();
		long seconds = (now.getTime() - upTime.getTime()) / 1000;
		StringBuilder sb = new StringBuilder();
		sb.append(job.getId() + " |upTime:"
					+ getDuration(seconds));
		getSpeedInfoForPlugin(job.getReader(), sb,now.getTime());
		for (Processor process : job.getProcessors()) {
			getSpeedInfoForPlugin(process, sb,now.getTime());
		}
		for (AbstractWriter writer : job.getWriters()) {
			getSpeedInfoForPlugin(writer, sb,now.getTime());
		}
		getSpeedInfoForPlugin(job.getErrorHandler(), sb,now.getTime());

		job.setSpeedInfo(sb.toString());
		return sb.toString();
	}

	public String getFinalReport(Job job){
		Date now = new Date();
		long seconds = (now.getTime() - upTime.getTime()) / 1000;
		StringBuilder sb = new StringBuilder();
		sb.append(job.getId() + " |upTime:"
					+ getDuration(seconds));
		getFinalSpeedForPlugin(job.getReader(), sb,seconds);
		for (Processor process : job.getProcessors()) {
			getFinalSpeedForPlugin(process, sb,seconds);
		}
		for (AbstractWriter writer : job.getWriters()) {
			getFinalSpeedForPlugin(writer, sb,seconds);
		}
		getFinalSpeedForPlugin(job.getErrorHandler(), sb,seconds);

		job.setSpeedInfo(sb.toString());
		return sb.toString();
	}
	private String getDuration(long seconds){
		String duration="";
		DecimalFormat decimalFormat = new DecimalFormat(".00");
		if (seconds >= 60 * 60 * 24)
			duration= decimalFormat.format((float) seconds / (60 * 60 * 24))
					+ "d|";
		else if (seconds >= 60 * 60)
			duration= decimalFormat.format((float) seconds / (60 * 60)) + "h|";
		else if (seconds >= 60)
			duration= decimalFormat.format((float) seconds / 60) + "m|";
		else
			duration= decimalFormat.format((float) seconds) + "s|";
		return duration;
		
	}
	private void getFinalSpeedForPlugin(AbstractPlugin plugin, StringBuilder sb,long timeStamp){
		
		sb.append(plugin.getName() + ":{");
		float speed = (plugin.getCounter()+1) /timeStamp;
		sb.append("Total :" + (plugin.getCounter()+1) +  " |speed:" + speed + " L/s } ");
	}
	private void getSpeedInfoForPlugin(AbstractPlugin plugin, StringBuilder sb,long timeStamp) {
		long increment = plugin.getCounter() - speedInfo.get(plugin.getId()).getCounter();
		sb.append(plugin.getName() + ":{");
		long increTime=(timeStamp-speedInfo.get(plugin.getId()).getTime())/1000;
		float speed = increment /increTime;
		sb.append("Total :" + plugin.getCounter() +  " |speed:" + speed + " L/s } ");
		speedInfo.put(plugin.getId(), new SpeedMeta(plugin.getCounter(),timeStamp));
	}

	public Map<String, SpeedMeta> getSpeedInfo() {
		return speedInfo;
	}

}
